package ar.com.solidussource.framework.backend.bo.crud.impl;

import java.io.Serializable;
import java.util.List;

import javax.persistence.PersistenceException;

import org.apache.log4j.Logger;

import ar.com.solidussource.framework.backend.bo.crud.GenericCRUDBO;
import ar.com.solidussource.framework.backend.bo.exception.BusinessException;
import ar.com.solidussource.framework.backend.dao.crud.GenericCRUDDao;
import ar.com.solidussource.framework.backend.dao.filter.Filter;
import ar.com.solidussource.framework.backend.dao.filter.Page;
import ar.com.solidussource.framework.backend.dao.filter.Result;

/**
 * Implementacion del {@link BusinessObject} para operaciones genericas CRUD con
 * integracion al modelo de {@link Filter} y {@link Page}. Esta implementacion
 * de {@link GenericCRUDBO} puede ser utilizada por las aplicaciones, y debe
 * existir una instancia por cada clase que se quiera trabajar.<br>
 * Para poder instanciar este {@link BusinessObject} se requiere que el
 * {@link GenericCRUDDao} correspondiente este instanciado e inyectado en la
 * propiedad 'genericDao'
 */
public class GenericCRUDBOImpl<T> implements GenericCRUDBO<T> {

	private static final Logger logger = Logger.getLogger(GenericCRUDBOImpl.class);
	/**
	 * instancia del DAo generico configurado para la clase correspondiente
	 */
	private GenericCRUDDao<T> genericDao;

	public long count(Filter filter) throws BusinessException {
		try{
			return this.getGenericDao().count(filter);
		}catch (PersistenceException e){
			logger.error("BO Generico CRUD - count ", e);
			throw new BusinessException(e.getMessage(), e);
		}
	}

	public void delete(T instance) throws BusinessException {
		try{
			this.getGenericDao().delete(instance);
		}catch (PersistenceException e){
			logger.error("BO Generico CRUD - delete ", e);
			throw new BusinessException(e.getMessage(), e);
		}

	}

	public List<T> getAll() throws BusinessException {
		try{
			return this.getGenericDao().getAll();
		}catch (PersistenceException e){
			logger.error("BO Generico CRUD - getAll", e);
			throw new BusinessException(e.getMessage(), e);
		}
	}

	public Result<T> getAll(Page page) throws BusinessException {
		try{
			return this.getGenericDao().getAll(page);
		}catch (PersistenceException e){
			logger.error("BO Generico CRUD - getAllPage ", e);
			throw new BusinessException(e.getMessage(), e);
		}
	}

	public Result<T> getAll(Filter filter, Page page) throws BusinessException {
		try{
			return this.getGenericDao().getAll(filter, page);
		}catch (PersistenceException e){
			logger.error("BO Generico CRUD - getAllFilterPAge", e);
			throw new BusinessException(e.getMessage(), e);
		}
	}

	public T getById(Serializable id) throws BusinessException {
		try{
			return this.getGenericDao().getById(id);
		}catch (PersistenceException e){
			logger.error("BO Generico CRUD - getById", e);
			throw new BusinessException(e.getMessage(), e);
		}
	}

	public T saveNew(T instance) throws BusinessException {
		try{
			return this.getGenericDao().saveNew(instance);
		}catch (PersistenceException e){
			logger.error("BO Generico CRUD - saveNew", e);
			throw new BusinessException(e.getMessage(), e);
		}
	}

	public T saveOrUpdate(T instance) throws BusinessException {
		try{
			return this.getGenericDao().saveOrUpdate(instance);
		}catch (PersistenceException e){
			logger.error("BO Generico CRUD - saveOrupdate", e);
			throw new BusinessException(e.getMessage(), e);
		}
	}

	/**
	 * @return the genericDao
	 */
	public GenericCRUDDao<T> getGenericDao() {
		return genericDao;
	}

	/**
	 * @param genericDao the genericDao to set
	 */
	public void setGenericDao(GenericCRUDDao<T> genericDao) {
		this.genericDao = genericDao;
	}

}